home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Games / ADoomPPC / src / r_plane.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-16  |  9.8 KB  |  501 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Here is a core component: drawing the floors and ceilings,
  21. //     while maintaining a per column clipping list only.
  22. //    Moreover, the sky areas have to be determined.
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_plane.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30. #include <stdlib.h>
  31.  
  32. #include "i_system.h"
  33. #include "z_zone.h"
  34. #include "w_wad.h"
  35.  
  36. #include "doomdef.h"
  37. #include "doomstat.h"
  38.  
  39. #include "r_local.h"
  40. #include "r_sky.h"
  41.  
  42.  
  43.  
  44. planefunction_t        floorfunc;
  45. planefunction_t        ceilingfunc;
  46.  
  47. //
  48. // opening
  49. //
  50.  
  51. // Here comes the obnoxious "visplane".
  52. //#define MAXVISPLANES    128
  53. #define MAXVISPLANES    256
  54. FAR visplane_t        visplanes[MAXVISPLANES];
  55. visplane_t*        lastvisplane;
  56. visplane_t*        floorplane;
  57. visplane_t*        ceilingplane;
  58.  
  59. // ?
  60. //#define MAXOPENINGS    SCREENWIDTH*64
  61. #define MAXOPENINGS    SCREENWIDTH*128
  62. //FAR short        openings[MAXOPENINGS];
  63. short            *openings;
  64. short*            lastopening;
  65.  
  66.  
  67. //
  68. // Clip values are the solid pixel bounding the range.
  69. //  floorclip starts out SCREENHEIGHT
  70. //  ceilingclip starts out -1
  71. //
  72. //short            floorclip[SCREENWIDTH];
  73. //short            ceilingclip[SCREENWIDTH];
  74. short            *floorclip;
  75. short            *ceilingclip;
  76.  
  77.  
  78. //
  79. // spanstart holds the start of a plane span
  80. // initialized to 0 at start
  81. //
  82. //FAR int            spanstart[SCREENHEIGHT];
  83. //FAR int            spanstop[SCREENHEIGHT];
  84. int                *spanstart;
  85. int                *spanstop;
  86.  
  87. //
  88. // texture mapping
  89. //
  90. lighttable_t**        planezlight;
  91. fixed_t            planeheight;
  92.  
  93. //FAR fixed_t        yslope[SCREENHEIGHT];
  94. //FAR fixed_t        distscale[SCREENWIDTH];
  95. fixed_t            *yslope;
  96. fixed_t            *distscale;
  97. fixed_t            basexscale;
  98. fixed_t            baseyscale;
  99.  
  100. //FAR fixed_t        cachedheight[SCREENHEIGHT];
  101. //FAR fixed_t        cacheddistance[SCREENHEIGHT];
  102. //FAR fixed_t        cachedxstep[SCREENHEIGHT];
  103. //FAR fixed_t        cachedystep[SCREENHEIGHT];
  104. fixed_t            *cachedheight;
  105. fixed_t            *cacheddistance;
  106. fixed_t            *cachedxstep;
  107. fixed_t            *cachedystep;
  108.  
  109.  
  110. void resinit_r_plane (void)  //called before anything else
  111. {
  112.   int i;
  113.  
  114.   //use calloc instead of malloc in case doom depends on global vars being
  115.   //initialized to 0
  116.   for (i = 0; i < MAXVISPLANES; i++) {
  117.     unsigned short *blah;
  118.  
  119.     blah = (unsigned short *)I_calloc(SCREENWIDTH*2+4, sizeof(unsigned short));
  120.     visplanes[i].top = blah + 1;
  121.     visplanes[i].bottom = blah + SCREENWIDTH + 3;
  122.   }
  123.   openings = (short *)I_calloc (MAXOPENINGS, sizeof(short));
  124.   floorclip = (short *)I_calloc (SCREENWIDTH, sizeof(short));
  125.   ceilingclip = (short *)I_calloc (SCREENWIDTH, sizeof(short));
  126.   spanstart = (int *)I_calloc (SCREENHEIGHT, sizeof(int));
  127.   spanstop = (int *)I_calloc (SCREENHEIGHT, sizeof(int));
  128.  
  129.   yslope = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  130.   distscale = (fixed_t *)I_calloc (SCREENWIDTH, sizeof(fixed_t));
  131.   cachedheight = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  132.   cacheddistance = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  133.   cachedxstep = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  134.   cachedystep = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  135. }
  136.  
  137.  
  138. //
  139. // R_InitPlanes
  140. // Only at game startup.
  141. //
  142. void R_InitPlanes (void)
  143. {
  144.   // Doh!
  145. }
  146.  
  147.  
  148. //
  149. // R_MapPlane
  150. //
  151. // Uses global vars:
  152. //  planeheight
  153. //  ds_source
  154. //  basexscale
  155. //  baseyscale
  156. //  viewx
  157. //  viewy
  158. //
  159. // BASIC PRIMITIVE
  160. //
  161. void
  162. R_MapPlane
  163. ( int        y,
  164.   int        x1,
  165.   int        x2 )
  166. {
  167.     angle_t    angle;
  168.     fixed_t    distance;
  169.     fixed_t    length;
  170.     unsigned    index;
  171.     
  172. #ifdef RANGECHECK
  173.     if (x2 < x1
  174.     || x1<0
  175.     || x2>=viewwidth
  176.     || (unsigned)y>viewheight)
  177.     {
  178.     I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
  179.     }
  180. #endif
  181.  
  182.     if (planeheight != cachedheight[y])
  183.     {
  184.     cachedheight[y] = planeheight;
  185.     distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
  186.     ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
  187.     ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
  188.     }
  189.     else
  190.     {
  191.     distance = cacheddistance[y];
  192.     ds_xstep = cachedxstep[y];
  193.     ds_ystep = cachedystep[y];
  194.     }
  195.     
  196.     length = FixedMul (distance,distscale[x1]);
  197.     angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
  198.     ds_xfrac = viewx + FixedMul(finecosine[angle], length);
  199.     ds_yfrac = -viewy - FixedMul(finesine[angle], length);
  200.  
  201.     if (fixedcolormap)
  202.     ds_colormap = fixedcolormap;
  203.     else
  204.     {
  205.     index = distance >> LIGHTZSHIFT;
  206.     
  207.     if (index >= MAXLIGHTZ )
  208.         index = MAXLIGHTZ-1;
  209.  
  210.     ds_colormap = planezlight[index];
  211.     }
  212.     
  213.     ds_y = y;
  214.     ds_x1 = x1;
  215.     ds_x2 = x2;
  216.  
  217.     // high or low detail
  218.     spanfunc ();    
  219. }
  220.  
  221.  
  222. //
  223. // R_ClearPlanes
  224. // At begining of frame.
  225. //
  226. void R_ClearPlanes (void)
  227. {
  228.     int        i;
  229.     angle_t    angle;
  230.     
  231.     // opening / clipping determination
  232.     for (i=0 ; i<viewwidth ; i++)
  233.     {
  234.     floorclip[i] = viewheight;
  235.     ceilingclip[i] = -1;
  236.     }
  237.  
  238.     lastvisplane = visplanes;
  239.     lastopening = openings;
  240.     
  241.     // texture calculation
  242.     // memset (cachedheight, 0, sizeof(cachedheight));
  243.     memset (cachedheight, 0, SCREENHEIGHT * sizeof(fixed_t));
  244.  
  245.     // left to right mapping
  246.     angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
  247.     
  248.     // scale will be unit scale at SCREENWIDTH/2 distance
  249.     basexscale = FixedDiv (finecosine[angle],centerxfrac);
  250.     baseyscale = -FixedDiv (finesine[angle],centerxfrac);
  251. }
  252.  
  253.  
  254.  
  255.  
  256. //
  257. // R_FindPlane
  258. //
  259. visplane_t*
  260. R_FindPlane
  261. ( fixed_t    height,
  262.   int        picnum,
  263.   int        lightlevel )
  264. {
  265.     visplane_t*    check;
  266.     
  267.     if (picnum == skyflatnum)
  268.     {
  269.     height = 0;            // all skys map together
  270.     lightlevel = 0;
  271.     }
  272.     
  273.     for (check=visplanes; check<lastvisplane; check++)
  274.     {
  275.     if (height == check->height
  276.         && picnum == check->picnum
  277.         && lightlevel == check->lightlevel)
  278.     {
  279.         break;
  280.     }
  281.     }
  282.     
  283.             
  284.     if (check < lastvisplane)
  285.     return check;
  286.         
  287.     if (lastvisplane - visplanes == MAXVISPLANES)
  288.     I_Error ("R_FindPlane: no more visplanes");
  289.         
  290.     lastvisplane++;
  291.  
  292.     check->height = height;
  293.     check->picnum = picnum;
  294.     check->lightlevel = lightlevel;
  295.     check->minx = SCREENWIDTH;
  296.     check->maxx = -1;
  297.     
  298.     //memset (check->top,0xff,sizeof(check->top));
  299.     memset (check->top,0xff,SCREENWIDTH * sizeof(unsigned short));
  300.         
  301.     return check;
  302. }
  303.  
  304.  
  305. //
  306. // R_CheckPlane
  307. //
  308. visplane_t*
  309. R_CheckPlane
  310. ( visplane_t*    pl,
  311.   int        start,
  312.   int        stop )
  313. {
  314.     int        intrl;
  315.     int        intrh;
  316.     int        unionl;
  317.     int        unionh;
  318.     int        x;
  319.     
  320.     if (start < pl->minx)
  321.     {
  322.     intrl = pl->minx;
  323.     unionl = start;
  324.     }
  325.     else
  326.     {
  327.     unionl = pl->minx;
  328.     intrl = start;
  329.     }
  330.     
  331.     if (stop > pl->maxx)
  332.     {
  333.     intrh = pl->maxx;
  334.     unionh = stop;
  335.     }
  336.     else
  337.     {
  338.     unionh = pl->maxx;
  339.     intrh = stop;
  340.     }
  341.  
  342.     for (x=intrl ; x<= intrh ; x++)
  343.     //if (pl->top[x] != 0xff)
  344.     if (pl->top[x] != 0xffff)
  345.         break;
  346.  
  347.     if (x > intrh)
  348.     {
  349.     pl->minx = unionl;
  350.     pl->maxx = unionh;
  351.  
  352.     // use the same one
  353.     return pl;        
  354.     }
  355.     
  356.     // make a new visplane
  357.     lastvisplane->height = pl->height;
  358.     lastvisplane->picnum = pl->picnum;
  359.     lastvisplane->lightlevel = pl->lightlevel;
  360.     
  361.     pl = lastvisplane++;
  362.     pl->minx = start;
  363.     pl->maxx = stop;
  364.  
  365.     //memset (pl->top,0xff,sizeof(pl->top));
  366.     memset (pl->top,0xff,SCREENWIDTH * sizeof(unsigned short));
  367.  
  368.     return pl;
  369. }
  370.  
  371.  
  372. //
  373. // R_MakeSpans
  374. //
  375. void
  376. R_MakeSpans
  377. ( int        x,
  378.   int        t1,
  379.   int        b1,
  380.   int        t2,
  381.   int        b2 )
  382. {
  383.     while (t1 < t2 && t1<=b1)
  384.     {
  385.     R_MapPlane (t1,spanstart[t1],x-1);
  386.     t1++;
  387.     }
  388.     while (b1 > b2 && b1>=t1)
  389.     {
  390.     R_MapPlane (b1,spanstart[b1],x-1);
  391.     b1--;
  392.     }
  393.     
  394.     while (t2 < t1 && t2<=b2)
  395.     {
  396.     spanstart[t2] = x;
  397.     t2++;
  398.     }
  399.     while (b2 > b1 && b2>=t2)
  400.     {
  401.     spanstart[b2] = x;
  402.     b2--;
  403.     }
  404. }
  405.  
  406.  
  407.  
  408. //
  409. // R_DrawPlanes
  410. // At the end of each frame.
  411. //
  412. void R_DrawPlanes (void)
  413. {
  414.     visplane_t*        pl;
  415.     int            light;
  416.     int            x;
  417.     int            stop;
  418.     int            angle;
  419.                 
  420. #ifdef RANGECHECK
  421.     if (ds_p - drawsegs > MAXDRAWSEGS)
  422.     I_Error ("R_DrawPlanes: drawsegs overflow (%i)",
  423.          ds_p - drawsegs);
  424.     
  425.     if (lastvisplane - visplanes > MAXVISPLANES)
  426.     I_Error ("R_DrawPlanes: visplane overflow (%i)",
  427.          lastvisplane - visplanes);
  428.     
  429.     if (lastopening - openings > MAXOPENINGS)
  430.     I_Error ("R_DrawPlanes: opening overflow (%i)",
  431.          lastopening - openings);
  432. #endif
  433.  
  434.     for (pl = visplanes ; pl < lastvisplane ; pl++)
  435.     {
  436.     if (pl->minx > pl->maxx)
  437.         continue;
  438.  
  439.     
  440.     // sky flat
  441.     if (pl->picnum == skyflatnum)
  442.     {
  443.         dc_iscale = pspriteiscale2>>detailshift;
  444.         
  445.         // Sky is allways drawn full bright,
  446.         //  i.e. colormaps[0] is used.
  447.         // Because of this hack, sky is not affected
  448.         //  by INVUL inverse mapping.
  449.         dc_colormap = colormaps;
  450.         dc_texturemid = skytexturemid;
  451.         for (x=pl->minx ; x <= pl->maxx ; x++)
  452.         {
  453.         dc_yl = pl->top[x];
  454.         dc_yh = pl->bottom[x];
  455.  
  456.         if (dc_yl <= dc_yh)
  457.         {
  458.             angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
  459.             dc_x = x;
  460.             dc_source = R_GetColumn(skytexture, angle);
  461.             colfunc ();
  462.         }
  463.         }
  464.         continue;
  465.     }
  466.     
  467.     // regular flat
  468.     ds_source = W_CacheLumpNum(firstflat +
  469.                    flattranslation[pl->picnum],
  470.                    PU_STATIC);
  471.     
  472.     planeheight = iabs(pl->height-viewz);
  473.     light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
  474.  
  475.     if (light >= LIGHTLEVELS)
  476.         light = LIGHTLEVELS-1;
  477.  
  478.     if (light < 0)
  479.         light = 0;
  480.  
  481.     planezlight = zlight[light];
  482.  
  483.     //pl->top[pl->maxx+1] = 0xff;
  484.     //pl->top[pl->minx-1] = 0xff;
  485.     pl->top[pl->maxx+1] = 0xffff;
  486.     pl->top[pl->minx-1] = 0xffff;
  487.         
  488.     stop = pl->maxx + 1;
  489.  
  490.     for (x=pl->minx ; x<= stop ; x++)
  491.     {
  492.         R_MakeSpans(x,pl->top[x-1],
  493.             pl->bottom[x-1],
  494.             pl->top[x],
  495.             pl->bottom[x]);
  496.     }
  497.     
  498.     Z_ChangeTag (ds_source, PU_CACHE);
  499.     }
  500. }
  501.